package com.xiaoxie.system.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.xiaoxie.system.config.DataSourceProperties;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

@Slf4j
public class DruidDataSourceBuilder {

    public static DruidDataSource build(DataSourceProperties properties, DruidDataSource dataSource) {
        if (dataSource == null) {
            dataSource = new DruidDataSource();
        }
        if (properties != null) {
            dataSource.setUrl(properties.getUrl());
            dataSource.setUsername(properties.getUsername());
            dataSource.setPassword(properties.getPassword());
            dataSource.setDriverClassName(properties.getDriverClassName());
            /* 配置初始化大小、最小、最大 */
            dataSource.setInitialSize(properties.getInitialSize());
            dataSource.setMaxActive(properties.getMaxActive());
            dataSource.setMinIdle(properties.getMinIdle());
            /* 配置获取连接等待超时的时间 */
            dataSource.setMaxWait(properties.getMaxWait());
            Properties connectProperties = new Properties();
            /* 配置驱动连接超时时间，检测数据库建立连接的超时时间，单位是毫秒 */
            connectProperties.setProperty("connectTimeout", String.valueOf(properties.getConnectTimeout()));
            /* 配置网络超时时间，等待数据库操作完成的网络超时时间，单位是毫秒 */
            connectProperties.setProperty("socketTimeout", String.valueOf(properties.getSocketTimeout()));
            dataSource.setConnectProperties(connectProperties);
            /* 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒 */
            dataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
            /* 配置一个连接在池中最小、最大生存的时间，单位是毫秒 */
            dataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());
            dataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());
            /*
             * 用来检测连接是否有效的sql，要求是一个查询语句，常用select 'x'。如果validationQuery为null，testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
             */
            dataSource.setValidationQuery(properties.getValidationQuery());
            /* 建议配置为true，不影响性能，并且保证安全性。申请连接的时候检测，如果空闲时间大于timeBetweenEvictionRunsMillis，执行validationQuery检测连接是否有效。 */
            dataSource.setTestWhileIdle(properties.isTestWhileIdle());
            /* 申请连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。 */
            dataSource.setTestOnBorrow(properties.isTestOnBorrow());
            /* 归还连接时执行validationQuery检测连接是否有效，做了这个配置会降低性能。 */
            dataSource.setTestOnReturn(properties.isTestOnReturn());
        }
        try {
            Connection connection = dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException("添加动态数据源失败，请检查数据库数据库连接等配置信息");
        }
        return dataSource;
    }
}
